<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>[Generic Component Framework v3] Getting started with GCF</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<!--link href="tabs.css" rel="stylesheet" type="text/css"-->
</head><body>
 <div id="wrapper">
    <div id="logo_box">
        <a class="img_link" href="https://github.com/pnudupa/gcf" target="_blank" ><img style="float:left;margin-left:10px;margin-top:5px;margin-bottom:5px;"src="header_gcf_logo.jpg" alt="GCF LOGO"/></a>
        <a class="img_link" href="https://www.vcreatelogic.com/" target="_blank" ><img style="float:right;margin-right:10px; margin-top: 30px;" src="header_vcl_logo.jpg" alt="VCL LOGO"/></a>
        <div style="clear:both"></div>
    </div>
    <div class="nav">
        <ul>
            <li class="selectedpage">
                <a class="a-home" href="index.html" >
                    <span>Home</span>
                </a>
            </li>
            <li>
                <a class="a-classes " href="classes.html">
                    <span>All Classes</span>
                </a>
            </li>
            <li>
                <a class="a-home " href="gcf_modules.html">
                    <span>Modules</span>
                </a>
            </li>
            <li>
                <a class="a-home " href="gcf_guides_and_videos.html">
                    <span>Guides & Videos</span>
                </a>
            </li>
            <li>
                <a class="a-home " href="gcf_tools_and_inbuilt_components.html">
                    <span>Tools & Components</span>
                </a>
            </li>
        </ul>
    </div>
    <div id="main-content">
        <div class="inside">
        <div>
<!-- Generated by Doxygen 1.8.16 -->
</div><!-- top -->
<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Getting started with GCF </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#gcf_usinggcf">Using GCF</a></li>
<li class="level1"><a href="#gcf_keyconcepts">Key Concepts</a><ul><li class="level2"><a href="#gcf_modules">Modules in GCF</a></li>
<li class="level2"><a href="#gcf_application">GCF Application</a></li>
<li class="level2"><a href="#gcf_component">GCF Component</a></li>
<li class="level2"><a href="#gcf_component_settings">GCF Component Settings</a></li>
<li class="level2"><a href="#gcf_component_content">GCF Component Content</a></li>
<li class="level2"><a href="#gcf_objecttree">GCF Application Object Tree</a></li>
</ul>
</li>
<li class="level1"><a href="#gcf_getting_started_example">Simple Application example</a><ul><li class="level2"><a href="#gcf_example_directory_structure">Directory Structure</a></li>
<li class="level2"><a href="#gcf_example_project">SimpleApplication.pro</a></li>
<li class="level2"><a href="#gcf_simpleexample_application">SimpleExample - Application</a><ul><li class="level3"><a href="#gcf_simpleexample_application_1">AppWindowComponent class</a></li>
<li class="level3"><a href="#gcf_simpleexample_application_2">AppWindowComponent.xml - Content file</a></li>
<li class="level3"><a href="#gcf_simpleexample_application_3">Application.qrc - Resource file</a></li>
<li class="level3"><a href="#gcf_simpleexample_application_4">The main() function</a></li>
<li class="level3"><a href="#gcf_simpleexample_application_5">The Application.pro file</a></li>
<li class="level3"><a href="#gcf_simpleexample_application_6">Logs</a></li>
</ul>
</li>
<li class="level2"><a href="#gcf_simpleexample_calendarcomponent">The calendar component project</a><ul><li class="level3"><a href="#gcf_simpleexample_calendarcomponent_1">The CalendarComponent class</a></li>
<li class="level3"><a href="#gcf_simpleexample_calendarcomponent_2">The CalendarComponent.qrc file</a></li>
<li class="level3"><a href="#gcf_simpleexample_calendarcomponent_3">The CalendarComponent.xml content file</a></li>
<li class="level3"><a href="#gcf_simpleexample_calendarcomponent_4">The CalendarComponent.pro project file</a></li>
</ul>
</li>
<li class="level2"><a href="#gcf_simpleexample_dateeditcomponent">The date-edit component project</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p>GCF provides simple and robust framework for creating component based applications. A component, in GCF, is an entity that makes available one or more objects that can work in tandem with objects offered by other components in the application.</p>
<p>Components are loaded explicitly by an application. An application can invent its own mechanism for figuring out what components to load. It could for example hard-code names of components to load, or it could read them from a file, or it could load all components from a given directory. We refer to such applications (the ones that load GCF components) as GCF Applications.</p>
<p>Suggested video:</p>
<p> 
<video width="500" controls>
    <source src="../../../Videos/Getting-Started.mp4" type="video/mp4">
</video>
<p>If you are unable to view the embedded video above, please click <a href="http://player.vimeo.com/video/77784760" target="_blank">here</a> to view it on the web.</p>
</p>
<h1><a class="anchor" id="gcf_usinggcf"></a>
Using GCF</h1>
<p>GCF is simply a Qt/C++ library. Therefore using GCF would be like using any other C++ library in your Qt Application. Please read the article on " \ref gcf_howtoinstall " to understand ways to setup GCF on your computer.</p>
<p>It is important to remember at this point that you must </p><ul>
<li>Setup the <code>GCFDIR</code> environment variable to point to the source directory of GCF 3. After setting up this environment variable, you must be able to find </li>
<li>Setup the <code>QMAKEFEATURES</code> environment variable to point to $GCFDIR/QMakePRF folder. <code>$GCFDIR/QMakePRF/GCF3</code>.prf </li>
<li>On Windows, set <code>PATH</code> environment variable to include <code>GCFDIR%/Binary</code> </li>
<li>On Linux, set <code>LD_LIBRARY_PATH</code> environment variable to include <code>GCFDIR%/Binary</code> </li>
<li>On Mac, set <code>DYLD_LIBRARY_PATH</code> environment variable to include <code>GCFDIR%/Binary</code> </li>
<li>Restart your computer (or atleast Qt Creator)</li>
</ul>
<dl class="section note"><dt>Note</dt><dd>Environment variables are best set in .bashrc on Linux and Mac, so that they apply across login sessions.</dd></dl>
<p>Once setup, you can include GCF in your applications by simply including the following line in your project file.</p>
<pre class="fragment">CONFIG += GCF3
</pre><p><b>NOTE:</b> if for some reason the above <code>CONFIG</code> line doesnt work, then you can explicitly include the <code>prf</code> file as follows</p>
<pre class="fragment">include($$GCFDIR/QMakePRF/GCF3.prf)
</pre><h1><a class="anchor" id="gcf_keyconcepts"></a>
Key Concepts</h1>
<p>The following key-concepts are critical for understanding GCF and the application architecture it proposes. We recommend that you read this section even if you are a seasoned GCF developer.</p>
<ul>
<li><a class="el" href="gcf_getting_started.html#gcf_modules">Modules in GCF</a> </li>
<li><a class="el" href="gcf_getting_started.html#gcf_application">GCF Application</a> </li>
<li><a class="el" href="gcf_getting_started.html#gcf_component">GCF Component</a> </li>
<li><a class="el" href="gcf_getting_started.html#gcf_component_settings">GCF Component Settings</a> </li>
<li><a class="el" href="gcf_getting_started.html#gcf_component_content">GCF Component Content</a> </li>
<li><a class="el" href="gcf_getting_started.html#gcf_objecttree">GCF Application Object Tree</a></li>
</ul>
<p>For a comprehensive explanation of the component model offered by GCF, please read <a class="el" href="gcf_component_model.html">an article on that here</a>.</p>
<h2><a class="anchor" id="gcf_modules"></a>
Modules in GCF</h2>
<p>One of the central changes in version 3 of GCF is that it is now modular. GCF is now spread across the following modules</p>
<ul>
<li><b>GCF3</b> - core of GCF. Contains all component management mechanisms and a few helper classes. </li>
<li><b>GCFGui3</b> - offers support for GUI components. By default GCF3 offers support for components that use <code>QtCore</code> only. If you are writing GUI applications; you must link against <code>GCFGui3</code> module. </li>
<li><b>GCFQuick3</b> - offers support for QML components. [NOTE: This module is available only for Qt 5] </li>
<li><b>GCFIpc3</b> - offers support for inter-process communication between your GCF applications.</li>
</ul>
<p>If you want to use any of the above modules, you can simply add the module name to <code>CONFIG</code> line in the project file <b>OR</b> include the corresponding <code>prf</code> file. For example:</p>
<pre class="fragment">include($$GCFDIR/QMakePRF/GCFGui3.prf) # for using the GCFGui3 module

# OR

CONFIG += GCFQuick3
</pre><h2><a class="anchor" id="gcf_application"></a>
GCF Application</h2>
<p>The function of a GCF application is to provide a base component (also called application component), onto which all other components will merge their content objects; AND to load all components required for the application. Unlike GCF 2.x, in version 3 - you will have to create your own mechanism to figure out what components to load.</p>
<p>Your <b>application</b> should be written such that it links against <code>GCF3</code> OR <code>GCFGui3</code> OR <code>GCFQuick3</code> and creates an instance of any one subclass of <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a>.</p>
<div class="image">
<img src="class_g_c_f_1_1_application_services.png" alt=""/>
</div>
<p>Subclasses of <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a> bring both GCF and Qt application functionality your application. For instance </p><ul>
<li><a class="el" href="class_g_c_f_1_1_application.html">GCF::Application</a> brings <code>QCoreApplication</code> and <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a> to your applications. Applications written using this class can load only components that are written using <code>GCF3</code>. </li>
<li><a class="el" href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a> brings <code>QApplication</code> and <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a> to your applications. Such applications can load both <code>GCF3</code> components and <code>GCFGui3</code> components. [<b>NOTE:</b> such applications <b>cannot</b> load <code>GCFQuick3</code> components] </li>
<li><a class="el" href="class_g_c_f_1_1_qml_application.html">GCF::QmlApplication</a> brings <code>QGuiApplication</code> and <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a> to your applications. Such applications can load both <code>GCF3</code> components and <code>GCFQuick3</code> components. [<b>NOTE:</b> such applications <b>cannot</b> load <code>GCFGui3</code> components]</li>
</ul>
<p>In the rest of this document the term 'GCF application' AND 'application' will mean an executable Qt application that has an instance of <a class="el" href="class_g_c_f_1_1_application.html">GCF::Application</a> OR <a class="el" href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a> OR <a class="el" href="class_g_c_f_1_1_qml_application.html">GCF::QmlApplication</a>.</p>
<h2><a class="anchor" id="gcf_component"></a>
GCF Component</h2>
<p>Components are the building blocks of a GCF application. Components are basically instances if of <a class="el" href="class_g_c_f_1_1_component.html">GCF::Component</a> (or its subclasses <a class="el" href="class_g_c_f_1_1_qml_component.html">GCF::QmlComponent</a>, <a class="el" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a>). Instances of components can be </p><ul>
<li>created <b>explicitly</b> - by creating instances of your component classes and loading them using the <a class="el" href="class_g_c_f_1_1_component.html#a06e3573f06292a5211b81201ced61deb">GCF::Component::load()</a> method. </li>
<li>loaded <b>dynamically</b> from shared objects (or DLLs) - by making use of the <a class="el" href="class_g_c_f_1_1_application_services.html#a9fe06a88ce3a56f825cd2e11be4b0cf0">GCF::ApplicationServices::loadComponent()</a> function.</li>
</ul>
<p>To load components explicily you can either package your component class as a static library and link your application to it <b>OR</b> implement your component classes within your application codebase itself <b>OR</b> by explicitly link to a component (shared) library, such that its constructor can be accessed from your application.</p>
<p>To load components dynamically you must ensure that the component is installed in a known location ( <a class="el" href="group__gcf__core.html#ga33a0318fcd0b56eca9d73ba081c6ea2f">GCF::searchPathsForLibs()</a> ) AND that all dependencies of the component are available in <code>PATH%</code> or <code>$LD_LIBRARY_PATH</code> or <code>DYLD_LIBRARY_PATH</code>. You must also ensure that such components are "exposed" using the <code>GCF_EXPORT_COMPONENT</code> macro.</p>
<h2><a class="anchor" id="gcf_component_settings"></a>
GCF Component Settings</h2>
<p>Every component can optionally provide one settings file (in INI format). This settings file is read and written into during the course of the components life time. Read <a class="el" href="class_g_c_f_1_1_component.html#gcf_component_loading">Component loading (or initialization)</a> for more information.</p>
<h2><a class="anchor" id="gcf_component_content"></a>
GCF Component Content</h2>
<p>Every component can optionally provide a content file (in XML format). The content file will list out names and relationships of all content objects offered by the component. Read <a class="el" href="class_g_c_f_1_1_component.html#gcf_component_contentfile">Content File</a> for more information.</p>
<h2><a class="anchor" id="gcf_objecttree"></a>
GCF Application Object Tree</h2>
<p>One of the key objects that an application (instance of a subclass of <a class="el" href="class_g_c_f_1_1_application_services.html">GCF::ApplicationServices</a>) object creates is <b>object-tree</b> (which is an instance of <a class="el" href="class_g_c_f_1_1_object_tree.html">GCF::ObjectTree</a>). Content objects exposed by all components are registered in this object tree. The object tree can be accessed using <a class="el" href="class_g_c_f_1_1_application_services.html#a22657bd136cbf7a285cf0b273a40963a">GCF::ApplicationServices::objectTree()</a> method.</p>
<p>The root node of this object tree contains a pointer to the application object, which could be an instance of <a class="el" href="class_g_c_f_1_1_application.html">GCF::Application</a> OR <a class="el" href="class_g_c_f_1_1_qml_application.html">GCF::QmlApplication</a> OR <a class="el" href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a>.</p>
<p>Immediate children of this root node normally contain pointer to a component. Put in another way, if you application loads 20 components then there will be 20 child-nodes (<a class="el" href="class_g_c_f_1_1_object_tree_node.html">GCF::ObjectTreeNode</a>) of the root node in the object-tree; each node containing a pointer to one component. We shall call such nodes as component nodes.</p>
<p>Immediate children of component nodes contain points to content objects exposed by the component either via <a class="el" href="class_g_c_f_1_1_component.html#gcf_component_contentfile">Content File</a> or explicitly added via <a class="el" href="class_g_c_f_1_1_component.html#ac8791368cb9615392e6c9c2d380034f1">GCF::Component::addContentObject()</a> method. We shall call such nodes as content-object nodes.</p>
<p>There could be additional nodes in the object-tree; but the above kinds of are minimum.</p>
<p>Against each node we have a <code>QVariantMap</code> dictionary. This dictionary contains a set of key=value property-value pairs. The content of this dictionary is normally loaded while parsing the <a class="el" href="class_g_c_f_1_1_component.html#gcf_component_contentfile">Content File</a> or via the third parameter of <a class="el" href="class_g_c_f_1_1_component.html#ac8791368cb9615392e6c9c2d380034f1">GCF::Component::addContentObject()</a>. Object-tree-node for an object can be queried using GCF::ApplicationServices::node() method. And from that node the <code>QVariantMap</code> information dictionary can be fetched (or even altered).</p>
<p>In the rest of this document we will be using the term 'exposed object' a lot. The term 'exposed object' refers to an object that is registered into the application's object-tree. All components and their content-objects are 'exposed object's.</p>
<h1><a class="anchor" id="gcf_getting_started_example"></a>
Simple Application example</h1>
<p>This example shows you all the key-concepts (described above) in action. The application is architected such that it offers a base component (or the application component) and loads two other components. One of the components offers a <code>QDateEdit</code> widget as content-object and the other a <code>QCalendarWidget</code> as content-object. Both these content-objects are merged into a <code>QWidget</code> with <code>QVBoxLayout</code> offered by the application component. Feature wise; changing the date in <code>QDateEdit</code> alters the current date in <code>QCalendarWidget</code> and vice versa.</p>
<p>Through this example you will come to know</p>
<ul>
<li>How to create a GCF application, implement an application component and instantiate it. </li>
<li>How to create dynamically loadable components and load them from the application </li>
<li>How to authoer content-files such that content-objects can be merged with other components </li>
<li>How to create signal-slot connections from the content-file </li>
<li>How to write project files for applications and components </li>
<li>How to organize directory structure of your project</li>
</ul>
<p>At the end of this tutorial you will be able to see a window like the one shown below and interact with it.</p>
<div class="image">
<img src="simple_gui.png" alt=""/>
</div>
<p>Following sections are intented to be used as a hand-holding guide. Please follow the instructions proposed in the following section and actively participate in creating the example application. At the end of it, you will have an understanding of all key-concepts in GCF 3.</p>
<h2><a class="anchor" id="gcf_example_directory_structure"></a>
Directory Structure</h2>
<p>We recommend the following directory structure</p>
<pre class="fragment">- SimpleApplication # project folder
  - Binary # directory into which application binary is dumped
    - Components # directory into which components are dumped
  - Application # source code of the application
  - CalendarComponent # source code of calendar component
  - DateEditComponent # source code of date-edit component
</pre><p>Please create the above directory structure.</p>
<pre class="fragment">$ mkdir SimpleApplication
$ cd SimpleApplication
$ mkdir Binary
$ mkdir Application
$ mkdir CalendarComponent
$ mkdir DateEditComponent
$ cd Binary
$ mkdir Components
$ cd ..
$ touch SimpleApplication.pro
$ touch Application/Application.pro
$ touch CalendarComponent/CalendarComponent.pro
$ touch DateEditComponent/DateEditComponent.pro
</pre><h2><a class="anchor" id="gcf_example_project"></a>
SimpleApplication.pro</h2>
<p>Type the following contents into SimpleApplication.pro</p>
<pre class="fragment">TEMPLATE = subdirs
CONFIG += ordered

SUBDIRS += \
    Application \
    CalendarComponent \
    DateEditComponent
</pre><p>Essentially you are creating a <code>subdirs</code> Qt project and defining it as a collection of three sub-projects: <code>Application</code>, <code>CalendarComponent</code> and <code>DateEditComponent</code>.</p>
<h2><a class="anchor" id="gcf_simpleexample_application"></a>
SimpleExample - Application</h2>
<p>The application offers a base (or application) component. The only content object offered by this component is a <code>QWidget</code> window, that has a <code>QVBoxLayout</code> installed on it. This way content-objects from other components added to this window show up one below the other.</p>
<h3><a class="anchor" id="gcf_simpleexample_application_1"></a>
AppWindowComponent class</h3>
<p>Create a <code>AppWindowComponent</code> class as follows in a file called <code>AppWindowComponent.h</code>.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;GCF3/GuiComponent&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;QWidget&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">class </span>AppWindowComponent : <span class="keyword">public</span> <a class="code" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a></div>
<div class="line">{</div>
<div class="line">    Q_OBJECT <span class="comment">// recommended even if you dont have signals/slots/properties</span></div>
<div class="line">             <span class="comment">// or invokable methods in your component class.</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    <span class="comment">// Constructor</span></div>
<div class="line">    AppWindowComponent(QObject *parent=0) : GCF::<a class="code" href="class_g_c_f_1_1_gui_component.html#a07e764a562147615da48972af9079f3d">GuiComponent</a>(parent),</div>
<div class="line">    m_window(0) { }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line">    <span class="comment">// Destructor is protected, because we don&#39;t want instances of this</span></div>
<div class="line">    <span class="comment">// component to be created on the stack.</span></div>
<div class="line">    ~AppWindowComponent() { }</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Reimplemnted from GCF::Component to set the content file to load</span></div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">contentLoadEvent</a>(<a class="code" href="class_g_c_f_1_1_content_load_event.html">GCF::ContentLoadEvent</a> *e) {</div>
<div class="line">        <span class="keywordflow">if</span>(e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a033302e12daeb121564490a8f794417f">isPreContentLoad</a>())</div>
<div class="line">            e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a9a6a2ddca167a46d10d76111f64777e1">setContentFile</a>(<span class="stringliteral">&quot;:/AppWindowComponent.xml&quot;</span>);</div>
<div class="line">        <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::GuiComponent::contentLoadEvent</a>(e);</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Reimplemented to map content-object-name &#39;Window&#39; to m_window</span></div>
<div class="line">    QWidget *<a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">loadWidget</a>(<span class="keyword">const</span> QString &amp;name, <span class="keyword">const</span> QVariantMap &amp;info) {</div>
<div class="line">        m_window = <a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget</a>(name, info);</div>
<div class="line">        <span class="keywordflow">return</span> m_window;</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Reimplemented to show m_window upon activion of this component</span></div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="class_g_c_f_1_1_component.html#a464361482ef9039aee875940ae64306c">activationEvent</a>(<a class="code" href="class_g_c_f_1_1_activation_event.html">GCF::ActivationEvent</a> *e) {</div>
<div class="line">        <span class="keywordflow">if</span>(m_window)</div>
<div class="line">            m_window-&gt;show();</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Reimplemented to hide m_window upon deactivation of this component</span></div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="class_g_c_f_1_1_component.html#afb0e763839f42c3cca61d22c3ee7e1ce">deactivationEvent</a>(<a class="code" href="class_g_c_f_1_1_deactivation_event.html">GCF::DeactivationEvent</a> *e) {</div>
<div class="line">        <span class="keywordflow">if</span>(m_window)</div>
<div class="line">            m_window-&gt;hide()</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">private</span>:</div>
<div class="line">    <span class="comment">// Will be used for storing the pointer to top level widget for showing.</span></div>
<div class="line">    QWidget *m_window;</div>
<div class="line">};</div>
</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::Component::contentLoadEvent()</a>, <a class="el" href="class_g_c_f_1_1_component.html#a464361482ef9039aee875940ae64306c">GCF::Component::activationEvent()</a> and <a class="el" href="class_g_c_f_1_1_component.html#afb0e763839f42c3cca61d22c3ee7e1ce">GCF::Component::deactivationEvent()</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget()</a></dd></dl>
<h3><a class="anchor" id="gcf_simpleexample_application_2"></a>
AppWindowComponent.xml - Content file</h3>
<p><code>AppWindowComponent::contentLoadEvent()</code> was implemented in <code>AppWindowComponent</code> class to load a <code>AppWindowComponent.xml</code> content file. Type the following content into this XML file.</p>
<pre class="fragment">&lt;content&gt;
    &lt;object name="Window" type="widget" windowTitle="SimpleApplication" layout="vertical"&gt;
        &lt;property&gt;
            &lt;key&gt;minimumWidth&lt;/key&gt;
            &lt;value&gt;800&lt;/value&gt;
        &lt;/property&gt;
        &lt;property&gt;
            &lt;key&gt;minimumHeight&lt;/key&gt;
            &lt;value&gt;600&lt;/value&gt;
        &lt;/property&gt;
    &lt;/object&gt;
&lt;/content&gt;
</pre><p>The content file exposes the object with name <code>Window</code> of type <code>widget</code>. Sets the title of <code>Window</code> object as "SimpleApplication". It also sets the minimum width and minimum height of the <code>Window</code> as 800 and 600.</p>
<h3><a class="anchor" id="gcf_simpleexample_application_3"></a>
Application.qrc - Resource file</h3>
<p><code>AppWindowComponent::contentLoadEvent()</code> expects the content file to be available in the resource file system as <code></code>:/AppWindowComponent.xml. For this purpose, create a <code>Application.qrc</code> with the following contents.</p>
<pre class="fragment">&lt;RCC&gt;
    &lt;qresource prefix="/"&gt;
        &lt;file&gt;AppWindowComponent.xml&lt;/file&gt;
    &lt;/qresource&gt;
&lt;/RCC&gt;
</pre><h3><a class="anchor" id="gcf_simpleexample_application_4"></a>
The main() function</h3>
<p>The <code>main()</code> function is where we bring it all together. Type the following code into a <code>Main.cpp</code> file.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;GCF3/GuiApplication&gt;</span></div>
<div class="line"><span class="preprocessor">#include &quot;AppWindowComponent.h&quot;</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)</div>
<div class="line">{</div>
<div class="line">    <span class="comment">// Create instance of GCF::GuiApplication since we are using Qt</span></div>
<div class="line">    <span class="comment">// widgets module for the example application.</span></div>
<div class="line">    <a class="code" href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a> a(argc, argv);</div>
<div class="line">    a.setOrganizationName(<span class="stringliteral">&quot;MyCompany&quot;</span>);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Create object of component class AppWindowComponent in heap</span></div>
<div class="line">    AppWindowComponent *appWindowComp = <span class="keyword">new</span> AppWindowComponent;</div>
<div class="line">    appWindowComp-&gt;load();</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Load the components</span></div>
<div class="line">    a.loadComponent(<span class="stringliteral">&quot;Components/CalendarComponent&quot;</span>);</div>
<div class="line">    a.loadComponent(<span class="stringliteral">&quot;Components/DateEditComponent&quot;</span>);</div>
<div class="line"> </div>
<div class="line">    <span class="keywordflow">return</span> a.processArgumentsAndExec();</div>
<div class="line">}</div>
</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_component.html#a06e3573f06292a5211b81201ced61deb">GCF::Component::load()</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_application_services.html#a9fe06a88ce3a56f825cd2e11be4b0cf0">GCF::ApplicationServices::loadComponent()</a></dd></dl>
<h3><a class="anchor" id="gcf_simpleexample_application_5"></a>
The Application.pro file</h3>
<p>At this point the directory structure is as follows</p>
<pre class="fragment">- SimpleApplication
  - Binary
    - Components
  - Application
    - Application.pro # empty
    - Application.qrc
    - AppWindowComponent.h
    - AppWindowComponent.xml
    - Main.cpp
  - CalendarComponent
    - CalendarComponent.pro # empty
  - DateEditComponent
    - DateEditComponent.pro # empty
</pre><p>Type the following contents into <code>Application/Application.pro</code> </p>
<pre class="fragment">CONFIG += GCFGui3
CONFIG -= app_bundle
TEMPLATE = app
DESTDIR = $$PWD/../Binary
TARGET = SimpleApplication

SOURCES += Main.cpp
HEADERS += AppWindowComponent.h
RESOURCES += Application.qrc
OTHER_FILES += AppWindowComponent.xml
</pre><p>With this your application is now ready to compile. To compile your application run the following commands on a terminal (or command prompt).</p>
<pre class="fragment">$ cd path/to/SimpleApplication
$ qmake -recursive
$ make
</pre><p>At this point you can execute the <code>Binary/SimpleApplication</code> exeuctable. It will launch and show a blank window. This is because components <code>DateEditComponent</code> and <code>CalendarComponent</code> are not yet available.</p>
<h3><a class="anchor" id="gcf_simpleexample_application_6"></a>
Logs</h3>
<p>GCF has an internal logging engine, through with it logs a lot of information into a log file. The logs are generated into a directory called <code>Logs</code> under <a class="el" href="group__gcf__core.html#gaa1205a5652b4e65f87326058b7b86236">GCF::applicationDataDirectoryPath()</a>. Everytime your GCF application is launched, a new log file is created. To know more about logging please read the class documentation of <a class="el" href="class_g_c_f_1_1_log.html">GCF::Log</a>.</p>
<h2><a class="anchor" id="gcf_simpleexample_calendarcomponent"></a>
The calendar component project</h2>
<p>The calendar component would make available a <code>QCalendarWidget</code> content-object that would be merged into <code>Application.AppWindowComponent.Window</code>.</p>
<h3><a class="anchor" id="gcf_simpleexample_calendarcomponent_1"></a>
The CalendarComponent class</h3>
<p>The CalendarComponent class is defined as follows in <code>CalendarComponent.h</code> </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;GCF3/GuiComponent&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">class </span>CalendarComponent : <span class="keyword">public</span> <a class="code" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a></div>
<div class="line">{</div>
<div class="line">    Q_OBJECT</div>
<div class="line"> </div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    CalendarComponent(QObject *parent=0) : GCF::<a class="code" href="class_g_c_f_1_1_gui_component.html#a07e764a562147615da48972af9079f3d">GuiComponent</a>(parent) { }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line">    ~CalendarComponent() { }</div>
<div class="line"> </div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">contentLoadEvent</a>(<a class="code" href="class_g_c_f_1_1_content_load_event.html">GCF::ContentLoadEvent</a> *e) {</div>
<div class="line">        <span class="keywordflow">if</span>(e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a033302e12daeb121564490a8f794417f">isPreContentLoad</a>())</div>
<div class="line">            e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a9a6a2ddca167a46d10d76111f64777e1">setContentFile</a>(<span class="stringliteral">&quot;:/CalendarComponent.xml&quot;</span>);</div>
<div class="line">        <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::GuiComponent::contentLoadEvent</a>(e);</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    QWidget *<a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">loadWidget</a>(<span class="keyword">const</span> QString &amp;name, <span class="keyword">const</span> QVariantMap &amp;info) {</div>
<div class="line">        Q_UNUSED(info);</div>
<div class="line">        <span class="keywordflow">if</span>(name == <span class="stringliteral">&quot;Calendar&quot;</span>)</div>
<div class="line">            <span class="keywordflow">return</span> <span class="keyword">new</span> QCalendarWidget;</div>
<div class="line">        <span class="keywordflow">return</span> <a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget</a>(name, info);</div>
<div class="line">    }</div>
<div class="line">};</div>
</div><!-- fragment --><p>The <code>CalendarComponent</code> class requests loading of <code></code>:/CalendarComponent.xml settings file and offers a <code>QCalendarWidget</code> instance against <code>"Calendar"</code> name.</p>
<p>We need the component class to be 'exported' from the shared-library. For this we type the following code in <code>CalendarComponent.cpp</code> </p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;CalendarComponent.h&quot;</span></div>
<div class="line"> </div>
<div class="line">GCF_EXPORT_COMPONENT(CalendarComponent)</div>
</div><!-- fragment --><p>Using <a class="el" href="group__gcf__core.html#GCF_EXPORT_COMPONENT">GCF_EXPORT_MACRO</a> will ensure that the component class can be instantiated by a GCF Application. The macro basically declares a special "C" function that is used by <a class="el" href="class_g_c_f_1_1_application_services.html#a9fe06a88ce3a56f825cd2e11be4b0cf0">GCF::ApplicationServices::loadComponent()</a> to create an instance of your component.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::Component::contentLoadEvent()</a> </dd>
<dd>
<a class="el" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget()</a></dd></dl>
<h3><a class="anchor" id="gcf_simpleexample_calendarcomponent_2"></a>
The CalendarComponent.qrc file</h3>
<p><code>CalendarComponent::contentLoadEvent()</code> expects the content file to be available in the resource file system as <code></code>:/CalendarComponent.xml. For this purpose, create a CalendarComponent.qrc with the following contents.</p>
<pre class="fragment">&lt;RCC&gt;
    &lt;qresource prefix="/"&gt;
        &lt;file&gt;CalendarComponent.xml&lt;/file&gt;
    &lt;/qresource&gt;
&lt;/RCC&gt;
</pre><h3><a class="anchor" id="gcf_simpleexample_calendarcomponent_3"></a>
The CalendarComponent.xml content file</h3>
<p>Content file of this component will be as follows</p>
<pre class="fragment">&lt;content&gt;
    &lt;object name="Calendar" type="widget" parent="Application.AppWindowComponent.Window" /&gt;
&lt;/content&gt;
</pre><p>Notice how we make use of the <code>type</code> attribute to declare that the content-object is of type <code>widget</code>. Also notice the use of <code>parent</code> attribute to request merging of the <code>Calendar</code> content-object with <code>Application.AppWindowComponent.Window</code>.</p>
<h3><a class="anchor" id="gcf_simpleexample_calendarcomponent_4"></a>
The CalendarComponent.pro project file</h3>
<p>The project file of calendar component will contain the following</p>
<pre class="fragment">DESTDIR = $$PWD/../Binary/Components
TEMPLATE = lib
CONFIG -= app_bundle
CONFIG += GCFGui3

HEADERS += CalendarComponent.h
SOURCES += CalendarComponent.cpp
OTHER_FILES += CalendarComponent.xml
RESOURCES += CalendarComponent.qrc
</pre><p>At this point we have the <code>CalendarComponent</code> ready. But we still need the <code>DateEdit</code> component to complete <code>SimpleApplication</code>.</p>
<h2><a class="anchor" id="gcf_simpleexample_dateeditcomponent"></a>
The date-edit component project</h2>
<p>There is not much difference between the calendar-compont and the date-edit component. You start off by creating a <code>DateEditComponent.h</code> file with the following class definition</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &lt;GCF3/GuiComponent&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">class </span>DateEditComponent : <span class="keyword">public</span> <a class="code" href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a></div>
<div class="line">{</div>
<div class="line">    Q_OBJECT</div>
<div class="line"> </div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    DateEditComponent(QObject *parent=0) : GCF::GuiComponent(parent) { }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line">    ~DateEditComponent() { }</div>
<div class="line"> </div>
<div class="line">    <span class="keywordtype">void</span> <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">contentLoadEvent</a>(<a class="code" href="class_g_c_f_1_1_content_load_event.html">GCF::ContentLoadEvent</a> *e) {</div>
<div class="line">        <span class="keywordflow">if</span>(e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a033302e12daeb121564490a8f794417f">isPreContentLoad</a>())</div>
<div class="line">            e-&gt;<a class="code" href="class_g_c_f_1_1_content_load_event.html#a9a6a2ddca167a46d10d76111f64777e1">setContentFile</a>(<span class="stringliteral">&quot;:/DateEditComponent.xml&quot;</span>);</div>
<div class="line">        <a class="code" href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::GuiComponent::contentLoadEvent</a>(e);</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    QWidget *<a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">loadWidget</a>(<span class="keyword">const</span> QString &amp;name, <span class="keyword">const</span> QVariantMap &amp;info) {</div>
<div class="line">        Q_UNUSED(info);</div>
<div class="line">        <span class="keywordflow">if</span>(name == <span class="stringliteral">&quot;DateEdit&quot;</span>)</div>
<div class="line">            <span class="keywordflow">return</span> <span class="keyword">new</span> QDateEdit;</div>
<div class="line">        <span class="keywordflow">return</span> <a class="code" href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget</a>(name, info);</div>
<div class="line">    }</div>
<div class="line">};</div>
</div><!-- fragment --><p>Next you create a <code>DateEditComponent.cpp</code> file to expose the component class</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;DateTimeComponent.h&quot;</span></div>
<div class="line">GCF_EXPORT_COMPONENT(DateTimeComponent)</div>
</div><!-- fragment --><p>Next you create a <code>DateEditComponent.qrc</code> resource file as follows</p>
<pre class="fragment">&lt;RCC&gt;
    &lt;qresource prefix="/"&gt;
        &lt;file&gt;DateEditComponent.xml&lt;/file&gt;
    &lt;/qresource&gt;
&lt;/RCC&gt;
</pre><p>Next you create a <code>DateEditComponent.xml</code> content file as follows</p>
<pre class="fragment">&lt;content&gt;
    &lt;object name="DateTime" type="widget" parent="Application.AppWindowComponent.Window"
            layoutPosition="0" &gt; &lt;!-- so that the date-time shows at the top --&gt;

        &lt;connection&gt;
            &lt;sender&gt;clicked(QDate)&lt;/sender&gt;
            &lt;receiver&gt;CalendarComponent.Calendar::setSelectedDate(QDate)&lt;/receiver&gt;
        &lt;/connection&gt;
        &lt;connection&gt;
            &lt;sender&gt;CalendarComponent.DateEdit::clicked(QDate)&lt;/sender&gt;
            &lt;receiver&gt;setDate(QDate)&lt;/receiver&gt;
        &lt;/connection&gt;

    &lt;/object&gt;
&lt;/content&gt;
</pre><p>Notice the use of <code>connection</code> XML elements to install signal/slot connections. Read <a class="el" href="class_g_c_f_1_1_component.html#gcf_component_contentfile">Content File</a> for more information.</p>
<p>Finally you create <code>DateEditComponent.pro</code> project file as follows</p>
<pre class="fragment">DESTDIR = $$PWD/../Binary/Components
TEMPLATE = lib
CONFIG -= app_bundle
CONFIG += GCFGui3

HEADERS += DateEditComponent.h
SOURCES += DateEditComponent.cpp
OTHER_FILES += DateEditComponent.xml
RESOURCES += DateEditComponent.qrc
</pre><p>At this point the directory structure is as follows</p>
<pre class="fragment">- SimpleApplication
  - Binary
    - Components
  - Application
    - Application.pro
    - Application.qrc
    - AppWindowComponent.h
    - AppWindowComponent.xml
    - Main.cpp
  - CalendarComponent
    - CalendarComponent.pro
    - CalendarComponent.h
    - CalendarComponent.cpp
    - CalendarComponent.qrc
    - CalendarComponent.xml
  - DateEditComponent
    - DateEditComponent.pro
    - DateEditComponent.h
    - DateEditComponent.cpp
    - DateEditComponent.qrc
    - DateEditComponent.xml
</pre><p>With this your application is now ready to compile. To compile your application run the following commands on a terminal (or command prompt).</p>
<pre class="fragment">$ cd path/to/SimpleApplication
$ qmake -recursive
$ make
</pre><p>Now launch the <code>Binary/SimpleApplication</code> executable and notice the output. You will get a window as shown below.</p>
<div class="image">
<img src="simple_gui.png" alt=""/>
</div>
<p>Changing date in <code>QDateEdit</code> widget changes the date in <code>QCalendarWidget</code> and vice versa. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
<div class="ttc" id="aclass_g_c_f_1_1_component_html_a7b9e7071c2f4b483a4ee51b08b70835c"><div class="ttname"><a href="class_g_c_f_1_1_component.html#a7b9e7071c2f4b483a4ee51b08b70835c">GCF::Component::contentLoadEvent</a></div><div class="ttdeci">virtual void contentLoadEvent(GCF::ContentLoadEvent *e)</div><div class="ttdef"><b>Definition:</b> Component.cpp:1041</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_gui_component_html"><div class="ttname"><a href="class_g_c_f_1_1_gui_component.html">GCF::GuiComponent</a></div><div class="ttdoc">Extends GCF::Component to ease creation of GUI components.</div><div class="ttdef"><b>Definition:</b> GuiComponent.h:35</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_deactivation_event_html"><div class="ttname"><a href="class_g_c_f_1_1_deactivation_event.html">GCF::DeactivationEvent</a></div><div class="ttdoc">Contains parameters that describe a deactivation event.</div><div class="ttdef"><b>Definition:</b> Component.h:192</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_activation_event_html"><div class="ttname"><a href="class_g_c_f_1_1_activation_event.html">GCF::ActivationEvent</a></div><div class="ttdoc">Contains parameters that describe an activation event.</div><div class="ttdef"><b>Definition:</b> Component.h:177</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_content_load_event_html_a033302e12daeb121564490a8f794417f"><div class="ttname"><a href="class_g_c_f_1_1_content_load_event.html#a033302e12daeb121564490a8f794417f">GCF::ContentLoadEvent::isPreContentLoad</a></div><div class="ttdeci">bool isPreContentLoad() const</div><div class="ttdef"><b>Definition:</b> Component.h:166</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_component_html_afb0e763839f42c3cca61d22c3ee7e1ce"><div class="ttname"><a href="class_g_c_f_1_1_component.html#afb0e763839f42c3cca61d22c3ee7e1ce">GCF::Component::deactivationEvent</a></div><div class="ttdeci">virtual void deactivationEvent(GCF::DeactivationEvent *e)</div><div class="ttdef"><b>Definition:</b> Component.cpp:1475</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_gui_application_html"><div class="ttname"><a href="class_g_c_f_1_1_gui_application.html">GCF::GuiApplication</a></div><div class="ttdoc">Extends GCF::Application for GUI Applications.</div><div class="ttdef"><b>Definition:</b> GuiApplication.h:44</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_gui_component_html_a07e764a562147615da48972af9079f3d"><div class="ttname"><a href="class_g_c_f_1_1_gui_component.html#a07e764a562147615da48972af9079f3d">GCF::GuiComponent::GuiComponent</a></div><div class="ttdeci">GuiComponent(QObject *parent=nullptr)</div><div class="ttdef"><b>Definition:</b> GuiComponent.cpp:165</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_content_load_event_html"><div class="ttname"><a href="class_g_c_f_1_1_content_load_event.html">GCF::ContentLoadEvent</a></div><div class="ttdoc">Contains parameters that describe a content-load event.</div><div class="ttdef"><b>Definition:</b> Component.h:158</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_component_html_a464361482ef9039aee875940ae64306c"><div class="ttname"><a href="class_g_c_f_1_1_component.html#a464361482ef9039aee875940ae64306c">GCF::Component::activationEvent</a></div><div class="ttdeci">virtual void activationEvent(GCF::ActivationEvent *e)</div><div class="ttdef"><b>Definition:</b> Component.cpp:1442</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_content_load_event_html_a9a6a2ddca167a46d10d76111f64777e1"><div class="ttname"><a href="class_g_c_f_1_1_content_load_event.html#a9a6a2ddca167a46d10d76111f64777e1">GCF::ContentLoadEvent::setContentFile</a></div><div class="ttdeci">void setContentFile(const QString &amp;fileName)</div><div class="ttdef"><b>Definition:</b> Component.h:169</div></div>
<div class="ttc" id="aclass_g_c_f_1_1_gui_component_html_abede43b20eb5ed489fa73f4727311527"><div class="ttname"><a href="class_g_c_f_1_1_gui_component.html#abede43b20eb5ed489fa73f4727311527">GCF::GuiComponent::loadWidget</a></div><div class="ttdeci">virtual QWidget * loadWidget(const QString &amp;name, const QVariantMap &amp;info)</div><div class="ttdef"><b>Definition:</b> GuiComponent.cpp:427</div></div>
</div>
</div>
</div>
<div class="footer_content">
<table width="100%" class="footer">
<tr>
<td align="left" width="50%">Copyright &copy; 2013-2019,
 <a class="el" href="http://www.vcreatelogic.com" target="_black">VCreate Logic Private Limited</a></td>
<td align="right" width="50%"><a class="el" href="http://www.vcreatelogic.com/products/gcf" target="_black">GCF - Generic Component Framework</a></td>
</tr>
</table>
</div>
</div>
</body>
</html>
